package cn.edu.xmu.oomall.liquidation.controller;

import cn.edu.xmu.oomall.liquidation.constant.Constants;
import cn.edu.xmu.oomall.liquidation.model.bo.Liquidation;
import cn.edu.xmu.oomall.liquidation.model.vo.ExpenditureItemRetVo;
import cn.edu.xmu.oomall.liquidation.model.vo.LiquidationRetVo;
import cn.edu.xmu.oomall.liquidation.model.vo.SimpleShopRetVo;
import cn.edu.xmu.oomall.liquidation.model.vo.StartInfoVo;
import cn.edu.xmu.oomall.liquidation.service.LiquidationService;
import cn.edu.xmu.oomall.liquidation.service.StartLiquidationService;
import cn.edu.xmu.privilegegateway.annotation.aop.Audit;
import cn.edu.xmu.oomall.core.util.Common;
import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.privilegegateway.annotation.aop.LoginName;
import cn.edu.xmu.privilegegateway.annotation.aop.LoginUser;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import static cn.edu.xmu.privilegegateway.annotation.util.Common.cloneVo;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

@Api(value = "清算服务", tags = "清算服务")
@RestController
@RequestMapping(value = "/", produces = "application/json;charset=UTF-8")
public class LiquidationController {
    @Autowired
    private LiquidationService liquidationService;

    @Autowired
    private StartLiquidationService startLiquidationService;

    private LocalDateTime zonedDateTime2LocalDateTime(ZonedDateTime zonedDateTime) {
        if (zonedDateTime == null) {
            return null;
        } else {
            return zonedDateTime.withZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime();
        }
    }

    @ApiOperation(value = "获得清算单的所有状态")
    @ApiImplicitParams(value = {@ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true)})
    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功")})
    @GetMapping("/liquidation/states")
    public Object getAllLiquidationStates() {
        return Common.decorateReturnObject(liquidationService.getAllLiquidationStates());
    }

    @ApiOperation(value = "平台管理员或商家获取符合条件的清算单简单信息")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true),
            @ApiImplicitParam(paramType = "path", dataType = "Long", name = "shopId", value = "商品id", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "beginDate", value = "开始日期"),
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "endDate", value = "结束日期"),
            @ApiImplicitParam(paramType = "query", dataType = "Boolean", name = "state", value = "是否已打款"),
            @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "page", value = "页码"),
            @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "pageSize", value = "每页数目")})
    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功")})
    @Audit
    @GetMapping("/shops/{shopId}/liquidation")
    public Object getSimpleLiquidation(@PathVariable("shopId") Long shopId,
                                    @RequestParam(required = false) @DateTimeFormat(pattern = Constants.INPUT_DATE_TIME_FORMAT)ZonedDateTime beginDate,
                                    @RequestParam(required = false) @DateTimeFormat(pattern = Constants.INPUT_DATE_TIME_FORMAT)ZonedDateTime endDate,
                                    @RequestParam(required = false) Boolean state, @RequestParam(defaultValue = "1") Integer page,
                                    @RequestParam(defaultValue = "10") Integer pageSize) {
        if (beginDate != null && endDate != null && beginDate.isAfter(endDate)) {
            ReturnObject returnObject = new ReturnObject(ReturnNo.LATE_BEGINTIME);
            return Common.decorateReturnObject(returnObject);
        }
        ReturnObject returnObject = liquidationService.getSimpleLiquidation(shopId, zonedDateTime2LocalDateTime(beginDate),
                zonedDateTime2LocalDateTime(endDate), state, page, pageSize);
        return Common.decorateReturnObject(returnObject);
    }

    @ApiOperation(value = "查询指定清算单详情")
    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功")})
    @Audit
    @GetMapping("/shops/{shopId}/liquidation/{id}")
    public Object getLiquidationById(@PathVariable("shopId") Long shopId, @PathVariable("id")Long id) {
        ReturnObject returnObject = liquidationService.getLiquidationById(shopId, id);
        if (returnObject.getCode() == ReturnNo.OK) {
            Liquidation liquidation = (Liquidation) returnObject.getData();
            LiquidationRetVo liquidationRetVo = cloneVo(liquidation, LiquidationRetVo.class);
            liquidationRetVo.setShop(new SimpleShopRetVo(liquidation.getShopId(), liquidation.getShopName()));
            returnObject = new ReturnObject(liquidationRetVo);
        }
        return Common.decorateReturnObject(returnObject);
    }

    @ApiOperation(value = "管理员按条件查某笔的进账")
    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功")})
    @Audit
    @GetMapping("/shops/{shopId}/revenue")
    public Object getRevenueItem(@PathVariable("shopId") Long shopId, @RequestParam(required = false) Long orderId,
                                 @RequestParam(required = false) Long productId,
                                 @RequestParam(required = false) Long liquidationId,
                                 @RequestParam(defaultValue = "1") Integer page,
                                 @RequestParam(defaultValue = "10") Integer pageSize) {
        ReturnObject returnObject = liquidationService.getRevenueItem(shopId, orderId, productId, liquidationId, page, pageSize);
        return Common.decorateReturnObject(returnObject);
    }

    @ApiOperation(value = "管理员按条件查对应清算单的出账")
    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功")})
    @Audit
    @GetMapping("/shops/{shopId}/expenditure")
    public Object getExpenditure(@PathVariable("shopId") Long shopId, @RequestParam(required = false) Long orderId,
                                 @RequestParam(required = false) Long productId,
                                 @RequestParam(required = false) Long liquidationId,
                                 @RequestParam(defaultValue = "1") Integer page,
                                 @RequestParam(defaultValue = "10") Integer pageSize) {
        ReturnObject returnObject = liquidationService.getExpenditure(shopId, orderId, productId, liquidationId, page, pageSize);
        return Common.decorateReturnObject(returnObject);
    }

    @ApiOperation(value = "管理员按id查出账对应的进账")
    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功")})
    @Audit(departName = "liquidation")
    @GetMapping("/shops/{shopId}/expenditure/{id}/revenue")
    public Object getRevenueByExpenditureId(@PathVariable("shopId") Long shopId, @PathVariable("id") Long id) {
        ReturnObject returnObject = liquidationService.getRevenueByExpenditureId(shopId, id);
        if (returnObject.getCode() == ReturnNo.OK) {
            ExpenditureItemRetVo expenditureItemRetVo = cloneVo(returnObject.getData(), ExpenditureItemRetVo.class);
            returnObject = new ReturnObject(expenditureItemRetVo);
        }
        return Common.decorateReturnObject(returnObject);
    }

    @ApiOperation(value = "开始清算")
    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功")})
    @Audit
    @PutMapping("/shops/{shopId}/liquidation/start")
    public Object startLiquidations(@PathVariable("shopId") Long shopId, @RequestBody @Validated StartInfoVo startInfoVo,
                                    @LoginUser Long userId, @LoginName String userName) {
        if (shopId != 0) {
            return Common.decorateReturnObject(new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE));
        }
        //Todo
        ReturnObject returnObject = startLiquidationService.startLiquidations(startInfoVo, userId, userName);
        return Common.decorateReturnObject(returnObject);
    }


    @ApiOperation(value = "用户获取自己因分享得到收入返点的记录")
    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功")})
    @Audit
    @GetMapping("/pointrecords/revenue")
    public Object getCustomerAcquirePointChange(@LoginUser Long userId,
                                                @RequestParam(required = false) @DateTimeFormat(pattern = Constants.INPUT_DATE_TIME_FORMAT)ZonedDateTime beginDate,
                                                @RequestParam(required = false) @DateTimeFormat(pattern = Constants.INPUT_DATE_TIME_FORMAT)ZonedDateTime endDate,
                                                @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer pageSize) {
        if (beginDate != null && endDate != null && beginDate.isAfter(endDate)) {
            ReturnObject returnObject = new ReturnObject(ReturnNo.LATE_BEGINTIME);
            return Common.decorateReturnObject(returnObject);
        }
        ReturnObject returnObject = liquidationService.getCustomerAcquirePointChange(userId, zonedDateTime2LocalDateTime(beginDate),
                zonedDateTime2LocalDateTime(endDate), page, pageSize);
        return Common.decorateReturnObject(returnObject);
    }

    @ApiOperation(value = "用户获取自己因分享得到收入返点的记录")
    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功")})
    @Audit
    @GetMapping("/pointrecords/expenditure")
    public Object getCustomerLostPointChange(@LoginUser Long userId,
                                                @RequestParam(required = false) @DateTimeFormat(pattern = Constants.INPUT_DATE_TIME_FORMAT)ZonedDateTime beginDate,
                                                @RequestParam(required = false) @DateTimeFormat(pattern = Constants.INPUT_DATE_TIME_FORMAT)ZonedDateTime endDate,
                                                @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer pageSize) {
        if (beginDate != null && endDate != null && beginDate.isAfter(endDate)) {
            ReturnObject returnObject = new ReturnObject(ReturnNo.LATE_BEGINTIME);
            return Common.decorateReturnObject(returnObject);
        }
        ReturnObject returnObject = liquidationService.getCustomerLostPointChange(userId, zonedDateTime2LocalDateTime(beginDate),
                zonedDateTime2LocalDateTime(endDate), page, pageSize);
        return Common.decorateReturnObject(returnObject);
    }
}
